home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-04-13 | 3.5 KB | 174 lines | [TEXT/ttxt] |
- -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C)
- -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
- --
- class LINK2_LIST[E]
- --
- -- Two way linked list with internal automatic memorization of
- -- the last access.
- --
-
- inherit LINKED_COLLECTION[E] redefine first_link end;
-
- creation
- make, from_collection
-
- feature {LINKED_COLLECTION}
-
- first_link: LINK2[E];
-
- feature -- Creation and Modification :
-
- make is
- -- Make an empty list;
- do
- if first_link /= Void then
- first_link.free;
- end;
- first_link := Void;
- last_link := Void;
- upper := 0;
- mem_idx := 0;
- mem_lnk := Void;
- ensure
- count = 0
- end;
-
- feature -- Implementation of deferred :
-
- add_first(element: like item) is
- do
- if first_link = Void then
- !!first_link.make(element,Void,Void);
- last_link := first_link;
- upper := 1;
- mem_idx := 1;
- mem_lnk := first_link;
- else
- !!first_link.make(element,Void,first_link);
- first_link.next.set_previous(first_link);
- upper := upper + 1;
- mem_idx := mem_idx + 1;
- end;
- ensure then
- upper = 1 + old upper
- end;
-
- add_last(element: like item) is
- do
- if first_link = Void then
- !!first_link.make(element,Void,Void);
- last_link := first_link;
- upper := 1;
- mem_idx := 1;
- mem_lnk := first_link;
- else
- !!last_link.make(element,last_link,Void);
- last_link.previous.set_next(last_link);
- upper := upper + 1;
- end;
- end;
-
- add(element: like item; index: INTEGER) is
- local
- link: like first_link;
- do
- if index = 1 then
- add_first(element);
- elseif index = upper + 1 then
- add_last(element);
- else
- if (index - 1) /= mem_idx then
- go_item(index - 1);
- end;
- !!link.make(element,mem_lnk,mem_lnk.next);
- link.next.set_previous(link);
- mem_lnk.set_next(link);
- upper := upper + 1;
- end;
- end;
-
- remove_first is
- local
- mem: MEMORY;
- do
- if upper = 1 then
- make;
- else
- mem_lnk := first_link;
- first_link := first_link.next;
- first_link.set_previous(Void);
- mem.free(mem_lnk.to_pointer);
- mem_lnk := first_link;
- mem_idx := 1;
- upper := upper - 1;
- end;
- end;
-
- remove(index: INTEGER) is
- local
- mem: MEMORY;
- link: like first_link;
- do
- if index = 1 then
- remove_first;
- elseif index = upper then
- remove_last;
- else
- if (index - 1) /= mem_idx then
- go_item(index - 1);
- end;
- link := mem_lnk.next;
- mem_lnk.set_next(link.next);
- link.next.set_previous(mem_lnk);
- mem.free(link.to_pointer);
- upper := upper - 1;
- end;
- end;
-
- feature {NONE}
-
- go_item(index: INTEGER) is
- do
- if index > mem_idx then
- if (upper - index) < (index - mem_idx) then
- from
- mem_idx := upper;
- mem_lnk := last_link;
- until
- index = mem_idx
- loop
- mem_lnk := mem_lnk.previous;
- mem_idx := mem_idx - 1;
- end;
- else
- from
- until
- index = mem_idx
- loop
- mem_lnk := mem_lnk.next;
- mem_idx := mem_idx + 1;
- end;
- end
- elseif (mem_idx - index) < (index - 1) then
- from
- until
- index = mem_idx
- loop
- mem_lnk := mem_lnk.previous;
- mem_idx := mem_idx - 1;
- end;
- else
- from
- mem_idx := 1;
- mem_lnk := first_link;
- until
- index = mem_idx
- loop
- mem_lnk := mem_lnk.next;
- mem_idx := mem_idx + 1;
- end;
- end;
- end;
-
- end -- LINK2_LIST[E]
-